import java.io.*;
import java.util.*;
import java.lang.Float;
import java.math.*;
class FS {
	public static int flops;
	public static DeflatedNumber d;
	public static class DeflatedNumber {
		float s;
		float e;
		public DeflatedNumber(float s, float e) {
			this.s = s;
			this.e = e;
		}
	}

	static DeflatedNumber AddTwo(float a, float b) {
		flops += 3;
		float s = a + b;
		float e = 0;
		int aexponent = ((Float.floatToIntBits(a)) & 0x7f800000) >> 23;// - 127;
		int bexponent  = ((Float.floatToIntBits(b)) & 0x7f800000) >> 23;// - 127;
		if(aexponent < bexponent) {
			e = (b - s) + a;
		}
		else {
			e = (a - s) + b;
		}
		return new DeflatedNumber(s, e);
	}

	public static void main(String args[]) {
		flops = 0;
		DeflatedNumber d = new DeflatedNumber(0, 0);	
		float[] q = new float[200];

		// load numbers from a file
		long startTime = System.currentTimeMillis();
		float[] num_list = loadNumbersFromAFile(); 
		long endTime = System.currentTimeMillis();	
		System.out.println("time to load data " + (endTime - startTime));

		long startTime2 = System.currentTimeMillis();
		float sum = FastSum(num_list,num_list.length, q, 0);
		long endTime2 = System.currentTimeMillis();
		System.out.println("time to run " + (endTime2 - startTime2));
		System.out.println("flops " + flops);
		System.out.println(new BigDecimal(sum));
	}
	
	static float FastSum(float[] num_list,int n, float[] q, int c_q)
	{
		float s=0,s_p,s_n;
		int i,count=n;
		
		for(i=1;i<n;i++) {
			d = AddTwo(s,num_list[i]);
			s = d.s;
			num_list[i] = d.e;
		}

		while(true)
		{
			s_p = 0;
			s_n = 0;
			count=n - 1;
			for(i=1;i<n;i++)
			{
				if(num_list[i]>0) {
					d = AddTwo(s_p, num_list[i]);
					s_p = d.s;
					num_list[i] = d.e;
				}	
				else { 
					d = AddTwo(s_n, num_list[i]);
					s_n = d.s;
					num_list[i] = d.e;
				}	
				if(num_list[i]==0)
					count--;
			}
			for(i=0;i<c_q;i++)
			{
				if(q[i]>0) {
					d = AddTwo(s_p,q[i]);
					s_p = d.s;
					q[i] = d.e;
				}
				else {
					d = AddTwo(s_n,q[i]);
					s_n = d.s;
					q[i] = d.e;
				}
				if(q[i]	!= 0)
					count++;
			}

			do
			{
				flops += 2;
				d = AddTwo(s_p,s_n);
				s_p = d.s;
				s_n = d.e;
				d = AddTwo(s,s_p);
				s = d.s;
				s_p = d.e;	
				d = AddTwo(s,s_n);
				s = d.s;
				s_n = d.e;
			}while(s+(s_p+s_n)!=s);
			q[c_q++]=s_p;
			q[c_q++]=s_n;
			System.out.println("here");

			float est_s = (Math.ulp(max(Math.abs(s_p), Math.abs(s_n)))) * count;
			flops += 1;	
			if(s+est_s==s) 
			{
				d = AddTwo(s_p,s_n);
				s_p = d.s;
				s_n = d.e;
				flops += 6;
				if((s_p +  (est_s + s_n)) + s == s &&
				   (s_p + (-est_s + s_n)) + s == s)
					break;
				else
					FastSum(num_list,num_list.length,q,c_q);
			}
		}
		return s;
	}

	static float max(float a, float b) {
		if(a > b)
			return a;
		else 
			return b;
	}

	public static float[] loadNumbersFromAFile() {
		try {
			Vector<Float> v = new Vector<Float>();
			int i = 0;
			Scanner sc = new Scanner(new File("numbers"));
			while(sc.hasNextFloat()) {
				float temp = sc.nextFloat();
				v.add(temp);
				i++;
			}
			float[] num_list = new float[v.size()];
			i = 0;
			for(Float f: v) {
				num_list[i] = f.floatValue();
				i++;
			}
			return num_list;
		}
		catch(FileNotFoundException e) {

		}	
		return null;
	}
}
